import axios from 'axios';

import Config from '../../config';
import getAPIHeaders from '../get-api-headers';
import PayrollGroup from './payroll-group';

export interface GetPayoutsTodayResponse {
    payrollGroup : PayrollGroup;
    totalAmount : number;
}

export default class PayrollGroupManager {

    static getAll = async (): Promise<Array<PayrollGroup>> => {
        try {
            const call = await axios.get(Config.getAPI() + '/payroll-group/all', {
                headers: await getAPIHeaders(),
            });

            if (call.data['payroll_groups']) {
                const groups = new Array<PayrollGroup>();

                for (let i = 0; i < call.data['payroll_groups'].length; i++) {
                    groups.push(PayrollGroup.fromJSON(call.data['payroll_groups'][i]));
                }

                return groups;
            }
        } catch (exception) {
            console.log(exception);
        }

        return null;
    };

    static getByID = async (payrollGroupID: number): Promise<PayrollGroup> => {
        try {
            const url =
                Config.getAPI() + '/payroll-group/get-by-id?payroll_group_id=' + payrollGroupID;

            const call = await axios.get(url, {
                headers: await getAPIHeaders(),
            });

            if (call.data['payroll_group']) {
                return PayrollGroup.fromJSON(call.data['payroll_group']);
            }
        } catch (exception) {
            console.log(exception);
        }

        return null;
    };

    static getAllByPage = async (
        page = 0
    ): Promise<{
        hasMore: boolean;
        groups: Array<PayrollGroup>;
    }> => {
        try {
            const call = await axios.get(Config.getAPI() + `/payroll-group/all?page=${page}`, {
                headers: await getAPIHeaders(),
            });

            const result = {
                groups: [],
                hasMore: false,
            };

            result.hasMore = !call.data.no_more_results;

            if (call.data['payroll_groups']) {
                const groups = new Array<PayrollGroup>();

                for (let i = 0; i < call.data['payroll_groups'].length; i++) {
                    groups.push(PayrollGroup.fromJSON(call.data['payroll_groups'][i]));
                }

                result.groups = groups;
                return result;
            }
        } catch (exception) {
            console.log(exception);
        }

        return null;
    };

    static create = async (
        name: string,
        disbursementType: number,
        memberShare: number,
        minimumPayoutAmount: number,
        payoutSchedules: Array<number>
    ): Promise<PayrollGroup> => {
        const data = {
            [PayrollGroup.Keys.NAME]: name,
            [PayrollGroup.Keys.DISBURSEMENT_TYPE]: disbursementType,
            [PayrollGroup.Keys.MEMBER_SHARE]: memberShare,
            [PayrollGroup.Keys.MINIMUM_PAYOUT_AMOUNT]: minimumPayoutAmount,
            payout_schedules: payoutSchedules,
        };

        const call = await axios.post(`${Config.getAPI()}/payroll-group/create`, data, {
            headers: await getAPIHeaders(),
        });

        if (call.data?.error) {
            throw call.data.error;
        }

        if (call.data['payroll_group']) {
            return PayrollGroup.fromJSON(call.data['payroll_group']);
        }

        return null;
    };

    static update = async (
        payrollGroupID : number,
        name: string,
        disbursementType: number,
        memberShare: number,
        minimumPayoutAmount: number,
        payoutSchedules: Array<number>
    ): Promise<PayrollGroup> => {
        const data = {
            'payroll_group_id' : payrollGroupID, 
            [PayrollGroup.Keys.NAME]: name,
            [PayrollGroup.Keys.DISBURSEMENT_TYPE]: disbursementType,
            [PayrollGroup.Keys.MEMBER_SHARE]: memberShare,
            [PayrollGroup.Keys.MINIMUM_PAYOUT_AMOUNT]: minimumPayoutAmount,
            'payout_schedules': payoutSchedules
        };

        const call = await axios.put(`${Config.getAPI()}/payroll-group/update`, data, {
            headers: await getAPIHeaders(),
        });

        if (call.data?.error) {
            throw call.data.error;
        }

        if (call.data['payroll_group']) {
            return PayrollGroup.fromJSON(call.data['payroll_group']);
        }

        return null;
    };

    static getPayoutsToday = async (): Promise<Array<GetPayoutsTodayResponse>> => {
        try {
            const call = await axios.get(Config.getAPI() + '/payroll-group/payouts-today', {
                headers: await getAPIHeaders(),
            });

            if (call.data['payroll_groups']) {
                const list = new Array<GetPayoutsTodayResponse>();

                for (let i = 0; i < call.data['payroll_groups'].length; i++) {
                    const payrollGroup = PayrollGroup.fromJSON(call.data['payroll_groups'][i]['payroll_group']);
                    const totalAmount = call.data['payroll_groups'][i]['total_amount'];
                    list.push({ payrollGroup, totalAmount });
                }

                return list;
            }
        } catch (exception) {
            console.log(exception);
        }

        return null;
    };


    static delete = async (payrollGroupID: number): Promise<boolean> => {
        try {
            const url =
                Config.getAPI() + '/payroll-group/delete?payroll_group_id=' + payrollGroupID;

            const call = await axios.delete(url, {
                headers: await getAPIHeaders(),
            });

            return call.data['deleted'];
        } catch (exception) {
            console.log(exception);
        }

        return null;
    };
}
